<?php

namespace Common\Model;

/**
 * AppbaseModel 模型基类
 * 
 * 建议方法规范：
 *  get_paging_list, get_scope_fields
 *  item_save, item_delete
 *  refresh_cache
 * 
 * @author Su 2015-3-18 by sutroon
 * @since 1.1 <2015-4-23> SoChishun 从项目中分离到Common\Model
 * @since 1.2 <2015-6-19> SoChishun 新增$autoCheckFields默认字段(false),防止调用D('Common')的时候出错
 */
class CommonModel extends \Think\Model {

    // 不要检测字段
    protected $autoCheckFields = false;
    // 批量验证
    protected $patchValidate = true;

    public function __construct($connection = '') {
        parent::__construct('', '', $connection);
    }

    /**
     * 返回数组消息
     * @param mixed $status 数据库执行结果
     * @param mixed $info 错误消息
     * @return array array('status'=>false, 'info'=>'消息') 或 array('status'=>false, 'info'=>$result)
     * @since 1.0 <2015-3-26> SoChishun Added.
     * @since 2.0 <2015-6-10> SoChishun base_return_array() 重命名为 returnMsg()
     */
    protected function returnMsg($status, $info = false) {
        if (FALSE === $status || is_null($status)) {
            $msg = array('status' => false, 'info' => ($info ? $info : $this->getDbError()));
        } else {
            // 如果status是id值则info=status,否则info=info
            $msg = array('status' => true, 'info' => (true === $status ? $info : $status));
        }
        return $msg;
    }

    /**
     * 分页
     * @param \Think\Page $page 分页组件
     * @param array $options 数据库查询配置,默认array('field' => '*', 'order' => 'id desc', 'group' => null, 'table' => null, 'cache' => 10);
     * @param array $paging_options 分页配置,默认array('page_size' => C('USER.PAGE_SIZE'), 'page_params' => null);
     * @return false|array
     * @since 1.0 <2015-3-5> by sutroon
     * @since 1.1 <2015-4-23> SoChishun $options新增TABLE选项,支持视图查询
     * @since 1.2 <2015-4-24> SoChishun $options新增GROUPBY选项,支持联合查询;新增CACHE选项,支持缓存
     * @since 1.3 <2015-10-26> SoChishun 新增Addon支持
     * @since 2.0 <2015-11-13> SoChishun 重构
     * @since 2.1 <2016-5-6> SoChishun 修改page_size参数
     * @since 2.2 <2016-7-14> SoChishun 引用参数(&$pager)分页条字符串改为分页组件(&page), 新增pagesize变量
     */
    public function get_paging_list(\Think\Page &$page, $options = array(), $paging_options = array()) {
        $def_options = array('field' => '*', 'order' => 'id desc', 'table' => $this->tableName);
        $var_pagesize = C('VAR_PAGESIZE') ? C('VAR_PAGESIZE') : 'pagesize'; // 需设置Page.class.php ($this->nowPage = empty($_REQUEST[$this->p]) ? 1 : intval($_REQUEST[$this->p]);)
        $def_paging = array(
            'page_size' => (empty($_REQUEST[$var_pagesize]) ? C('LIST_ROWS') : intval($_REQUEST[$var_pagesize])), // 分页尺寸
            'page_params' => '', // 分页参数
        );
        $options = array_merge($def_options, $options);
        $paging_options = array_merge($def_paging, $paging_options);
        if (empty($paging_options['page_size'])) {
            $paging_options['page_size'] = 25;
        }
        $table = empty($options['table']) ? FALSE : $options['table'];
        if (empty($options['where'])) {
            $count = $table ? $this->table($table)->count() : $this->count();
        } else {
            $count = $table ? $this->table($table)->where($options['where'])->count() : $this->where($options['where'])->count();
        }
        // 2015-10-26 SoChishun 新增Addon支持
        if (defined('ADDON_NAME') && ADDON_NAME) {
            $paging_options['page_params']['addon'] = ADDON_NAME;
        }
        $page = new \Think\Page($count, $paging_options['page_size'], $paging_options['page_params']);
        $page->setConfig('header', '<span class="rows">每页 ' . $paging_options['page_size'] . ' 条,共 %TOTAL_ROW% 条记录,页次: %NOW_PAGE%/%TOTAL_PAGE%</span>');
        $page->setConfig('theme', '%FIRST% %UP_PAGE% %LINK_PAGE% %DOWN_PAGE% %END% %HEADER%');
        if ($page->listRows) {
            $options['limit'] = $page->firstRow . ',' . $page->listRows;
        }
        return $this->select($options);
    }

    /**
     * 获取所有层级子编号
     * @param integer $id
     * @return array
     * @since 1.0 2016-8-5 SoChishun Added.
     */
    public function base_get_child_ids($id, $pid_key = 'pid', $id_key = 'id') {
        if (is_null($id)) {
            return false;
        }
        $aout = array($id);
        $ids = $this->where(array($pid_key => $id))->getField($id_key, true);
        if ($ids) {
            foreach ($ids as $id1) {
                $aout[] = $id1;
                $ids2 = $this->where(array($pid_key => $id1))->getField($id_key, true);
                if ($ids2) {
                    foreach ($ids2 as $id2) {
                        $aout[] = $id2;
                        $ids3 = $this->where(array($pid_key => $id2))->getField($id_key, true);
                        if ($ids3) {
                            foreach ($ids3 as $id3) {
                                $aout[] = $id3;
                            }
                        }
                    }
                }
            }
        }
        return $aout;
    }

    /**
     * 返回树形列表
     * @param array $select_options
     * @param array $data_options
     * @return array
     * @throws \Exception
     * @since 1.0 <2015-3-25> SoChishun Added.
     * @since 2.0 <2015-10-22> SoChishun 重构,把参数整合成$select_options,$data-options
     * @since 2.1 <2015-10-26> SoChishun 新增where条件数组限制,比较规范
     * @since 2.2 2016-7-25 SoChishun 重构，控制参数名称改小写,去掉first_where.
     * @since 2.3 2016-8-3 SoChishun 新增id_key选项
     * @since 2.4 2016-8-5 SoChishun 去掉pid默认值选项,改为硬编码值0
     */
    public function base_get_tree_list($select_options = array(), $data_options = array()) {
        if (!empty($select_options['where']) && !is_array($select_options['where'])) {
            throw new \Exception('[TREE]WHERE不是有效数组!');
        }
        $_data_options = array('pid_field' => 'pid', 'id_key' => 'id', 'children_key' => 'children');
        $data_options = array_merge($_data_options, $data_options);
        if (empty($select_options['where'])) {
            $select_options['where'] = array($data_options['pid_field'] => 0);
        }
        return $this->base_get_tree_list_fn($select_options, $data_options);
    }

    /**
     * 返回树形列表的子方法
     * @param type $select_options
     * @param type $data_options
     * @return type
     * @since 1.0 <2015-3-25> SoChishun Added.
     * @since 1.1 <2015-7-31> SoChishun 新增$children_key参数
     * @since 2.0 <2015-10-22> SoChishun 重构,把参数整合成$select_options,$data-options
     * @since 2.1 2016-7-18 SoChishun 'chidren'空值由false改为array(),以匹配C#等强数据类型转换
     * @since 2.2 2016-7-25 SoChishun 重构，控制参数名称改小写.
     * @since 2.3 2016-8-5 SoChishun 修正array('id'=>$n)或pid=id时死循环的问题
     */
    function base_get_tree_list_fn($select_options = array(), $data_options = array()) {
        $list = $this->select($select_options);
        $aout = array();
        if ($list) {
            foreach ($list as $row) {
                $where = array($data_options['pid_field'] => $row[$data_options['id_key']]);
                // 必需有子项目且pid不等于id
                if ($this->where($where)->count() > 0 && $row[$data_options['pid_field']] != $row[$data_options['id_key']]) {
                    $select_options = array_merge($select_options, array('where' => $where));
                    $row[$data_options['children_key']] = $this->base_get_tree_list_fn($select_options, $data_options);
                } else {
                    $row[$data_options['children_key']] = array();
                }
                $aout[] = $row;
            }
        }
        return $aout;
    }

    /**
     * 获取规范的Url参数sort
     * <br />如: $sortby = sofunc_get_orderby(I('sort'))
     * @param string $sort
     * @return boolean
     * @since 1.0 2015-2-2 by sutroon
     */
    function sofunc_get_orderby($sort) {
        if ($sort) {
            switch ($sort[0]) {
                case 'D':
                    return substr($sort, 1) . ' DESC';
                case 'A':
                    return substr($sort, 1);
                default:
                    return $sort;
            }
        }
        return false;
    }

}
